package com.xz.xzutils.utils;

import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.awt.*;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import javax.swing.*;

/**
 * <p>
 *
 * </p>
 *
 * @author DONG.WANG17@HAND-CHINA.COM
 * @since 2025-01-07 22:33
 */
@Slf4j
public class EditorUtils {
    private static EditorUtils instance;

    // 启用单例模式
    private EditorUtils() {
    }

    public static EditorUtils getInstance() {
        if (instance == null) {
            instance = new EditorUtils();
        }
        return instance;
    }

    public void setText(Editor editor, String text) {
        WriteCommandAction.runWriteCommandAction(null, () -> {
            editor.getDocument().setText(text);
        });
    }

    public void reset(Editor editor) {
        WriteCommandAction.runWriteCommandAction(null, () -> {
            editor.getDocument().setText("");
            editor.getMarkupModel().removeAllHighlighters();
        });
    }

    public void addText(Editor editor, String text) {
        WriteCommandAction.runWriteCommandAction(null, () -> {
            editor.getDocument().insertString(editor.getDocument().getTextLength(), text);
        });
    }

    public void addLine(Editor editor, String text) {
        addLine(editor, text, null, 1000);
    }

    public void addLine(Editor editor, String text, Color color) {
        addLine(editor, text, color, 1000);
    }

    public void addLine(@NotNull Editor editor, @NotNull String text, Color color, int layer) {
        WriteCommandAction.runWriteCommandAction(null, () -> {
            Document document = editor.getDocument();
            document.insertString(document.getTextLength(), withLineBreaks(text));

            // 最新一行（排除换行符行）
            int lastTextLineNum = editor.getDocument().getLineCount() - 2;

            if (Objects.nonNull(color)) {

                TextAttributes attributes= new TextAttributes();
                attributes.setForegroundColor(color);

                MarkupModel markupModel = editor.getMarkupModel();
                RangeHighlighter rangeHighlighter = markupModel.addLineHighlighter(lastTextLineNum, layer, attributes);

            }
        });
    }


    // 移除指定高亮 只移除一个高亮 有时候不生效，有时候生效但是会莫名覆盖其他样式
    @Deprecated
    public void removeHighlighterByExternalName(Editor editor, TextAttributesKey textAttributesKey) {
        MarkupModel markupModel = editor.getMarkupModel();
        RangeHighlighter[] highlighters = markupModel.getAllHighlighters();
        for (RangeHighlighter highlighter : highlighters) {
            System.out.printf("执行时间 %s 已有高亮：%s %n", System.currentTimeMillis(), highlighter.getTextAttributesKey());
            boolean flag = Objects.nonNull(highlighter.getTextAttributesKey()) && highlighter.getTextAttributesKey().getExternalName().equals(textAttributesKey.getExternalName());
            if (flag) {
                System.out.println("移除高亮==============" + textAttributesKey.getExternalName());
                markupModel.removeHighlighter(highlighter);
            }
        }
    }

    // 移除指定行的高亮 方法1
    // note：这些一出高亮的方法都是直接移除一个范围内的，导致某些高亮被移除。
    @Deprecated
    public void removeHighlightByLine(Editor editor, int lineNum) {
        MarkupModel markupModel = editor.getMarkupModel();
        RangeHighlighter[] highlighters = markupModel.getAllHighlighters();
        for (RangeHighlighter highlighter : highlighters) {
            int startLine = editor.getDocument().getLineNumber(highlighter.getStartOffset());
            int endLine = editor.getDocument().getLineNumber(highlighter.getEndOffset());
            if (startLine <= lineNum && lineNum <= endLine) {
                System.out.printf("移除高亮：【%s】【%s】【%s】【%s】n", startLine, endLine, lineNum, highlighter.getLayer());
                markupModel.removeHighlighter(highlighter);
            }
        }
    }

    // 移除指定行的高亮 方法2
    @Deprecated
    public void removeHighlightByLine2(Editor editor, int lineNum) {
        Document document = editor.getDocument();
        MarkupModel markupModel = editor.getMarkupModel();
        int startOffset = document.getLineStartOffset(lineNum);
        int endOffset = document.getLineEndOffset(lineNum);
        for (RangeHighlighter highlighter : markupModel.getAllHighlighters()) {
            if (highlighter.getStartOffset() <= startOffset && highlighter.getEndOffset() >= endOffset) {
                markupModel.removeHighlighter(highlighter);
            }
        }
    }

    // 方法3
    @Deprecated
    public void removeHighlightByOffset(Editor editor, int startOffset, int endOffset) {
        MarkupModel markupModel = editor.getMarkupModel();
        RangeHighlighter[] highlighters = markupModel.getAllHighlighters();
        for (RangeHighlighter highlighter : highlighters) {
            if (highlighter.getStartOffset() == startOffset && highlighter.getEndOffset() == endOffset) {
                markupModel.removeHighlighter(highlighter);
            }
        }
    }

    public void addComponentPopupMenu(@NotNull Editor editor, @NotNull JPopupMenu jPopupMenu) {
        if (Objects.isNull(editor.getContentComponent().getComponentPopupMenu())) {
            editor.getContentComponent().setComponentPopupMenu(jPopupMenu);
        } else {
            editor.getContentComponent().getComponentPopupMenu().add(jPopupMenu);
        }
    }

    // 加上结尾换行符
    public String withLineBreaks(String textLine) {
        if (StringUtils.isNotBlank(textLine) && textLine.endsWith("\n")) {
            return textLine;
        }
        return textLine + "\n";
    }
}
